@farm.js/core 0.1.0-beta.3 → 0.1.0-beta.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (192) hide show
  1. package/dist/agent-runtime.d.mts +2 -1
  2. package/dist/agent-runtime.d.ts +2 -1
  3. package/dist/api/route-manager.cjs +313 -10
  4. package/dist/api/route-manager.cjs.map +1 -1
  5. package/dist/api/route-manager.d.mts +3 -2
  6. package/dist/api/route-manager.d.ts +3 -2
  7. package/dist/api/route-manager.mjs +6 -5
  8. package/dist/api/runtime.cjs +313 -10
  9. package/dist/api/runtime.cjs.map +1 -1
  10. package/dist/api/runtime.d.mts +2 -1
  11. package/dist/api/runtime.d.ts +2 -1
  12. package/dist/api/runtime.mjs +4 -3
  13. package/dist/api.cjs +642 -57
  14. package/dist/api.cjs.map +1 -1
  15. package/dist/api.d.mts +3 -2
  16. package/dist/api.d.ts +3 -2
  17. package/dist/api.mjs +29 -9
  18. package/dist/{app-DOKxo-LH.d.ts → app-BjN-da13.d.ts} +38 -3
  19. package/dist/{app-BB3Iu3xh.d.mts → app-CakAr8Be.d.mts} +38 -3
  20. package/dist/app-markdown.d.mts +2 -1
  21. package/dist/app-markdown.d.ts +2 -1
  22. package/dist/cache.cjs +395 -12
  23. package/dist/cache.cjs.map +1 -1
  24. package/dist/cache.d.mts +100 -6
  25. package/dist/cache.d.ts +100 -6
  26. package/dist/cache.mjs +8 -2
  27. package/dist/{chunk-XUBZ7JI4.mjs → chunk-2CUKEMVR.mjs} +187 -16
  28. package/dist/chunk-2CUKEMVR.mjs.map +1 -0
  29. package/dist/{chunk-5QH4IKY3.mjs → chunk-3U3ZUQAQ.mjs} +2 -2
  30. package/dist/{chunk-6WXJ54TC.mjs → chunk-65A7QIKI.mjs} +5 -5
  31. package/dist/{chunk-6WXJ54TC.mjs.map → chunk-65A7QIKI.mjs.map} +1 -1
  32. package/dist/{chunk-OHC6VCDI.mjs → chunk-AJWRO5WE.mjs} +521 -42
  33. package/dist/chunk-AJWRO5WE.mjs.map +1 -0
  34. package/dist/chunk-ALCLXXTY.mjs +187 -0
  35. package/dist/chunk-ALCLXXTY.mjs.map +1 -0
  36. package/dist/{chunk-XJSHJN4M.mjs → chunk-AOBXKNS5.mjs} +593 -49
  37. package/dist/chunk-AOBXKNS5.mjs.map +1 -0
  38. package/dist/{chunk-CSU4KJJF.mjs → chunk-C2ROET2V.mjs} +2 -2
  39. package/dist/{chunk-BIOIOWXZ.mjs → chunk-HNIQFZKB.mjs} +2 -2
  40. package/dist/{chunk-G5I34UA6.mjs → chunk-JDEOUK5V.mjs} +4 -4
  41. package/dist/{chunk-T543TMFY.mjs → chunk-NM3CRAAL.mjs} +3 -2
  42. package/dist/chunk-NM3CRAAL.mjs.map +1 -0
  43. package/dist/{chunk-LWMGIEJA.mjs → chunk-PFE6GMNE.mjs} +47 -37
  44. package/dist/chunk-PFE6GMNE.mjs.map +1 -0
  45. package/dist/{chunk-6VS6CKAV.mjs → chunk-QM746KUO.mjs} +8 -1
  46. package/dist/chunk-QM746KUO.mjs.map +1 -0
  47. package/dist/{chunk-SHRJG6OG.mjs → chunk-RBRLLZL5.mjs} +18 -3
  48. package/dist/chunk-RBRLLZL5.mjs.map +1 -0
  49. package/dist/{chunk-MH6FKW2I.mjs → chunk-SADGIRS2.mjs} +3 -3
  50. package/dist/{chunk-NRRFGX45.mjs → chunk-TQAEEJB4.mjs} +3 -3
  51. package/dist/{chunk-45LKHSHJ.mjs → chunk-UB5UOSHB.mjs} +24 -12
  52. package/dist/chunk-UB5UOSHB.mjs.map +1 -0
  53. package/dist/chunk-V3XURYJO.mjs +756 -0
  54. package/dist/chunk-V3XURYJO.mjs.map +1 -0
  55. package/dist/{chunk-5FW6PQ3J.mjs → chunk-VVKWFZAH.mjs} +41 -16
  56. package/dist/chunk-VVKWFZAH.mjs.map +1 -0
  57. package/dist/{chunk-HZYXGV4K.mjs → chunk-VY2UYN5R.mjs} +24 -4
  58. package/dist/chunk-VY2UYN5R.mjs.map +1 -0
  59. package/dist/{chunk-C33RALN7.mjs → chunk-W2CRQFF6.mjs} +79 -15
  60. package/dist/chunk-W2CRQFF6.mjs.map +1 -0
  61. package/dist/{chunk-JNYVN7YP.mjs → chunk-W4UIVMVI.mjs} +2 -2
  62. package/dist/{chunk-JNYVN7YP.mjs.map → chunk-W4UIVMVI.mjs.map} +1 -1
  63. package/dist/{chunk-LG3YINQN.mjs → chunk-Z5CQMP54.mjs} +3 -3
  64. package/dist/{client-DiViK9yK.d.mts → client-BT1mFQas.d.mts} +23 -4
  65. package/dist/{client-DpEBJbts.d.ts → client-Nn0q4eO4.d.ts} +23 -4
  66. package/dist/{client-plugins-CTnsZz_A.d.ts → client-plugins-Cw4qUGsw.d.ts} +6 -0
  67. package/dist/{client-plugins-Cnr0D3kk.d.mts → client-plugins-DQQ1adXM.d.mts} +6 -0
  68. package/dist/client-plugins.d.mts +2 -1
  69. package/dist/client-plugins.d.ts +2 -1
  70. package/dist/client.cjs +665 -82
  71. package/dist/client.cjs.map +1 -1
  72. package/dist/client.d.mts +70 -4
  73. package/dist/client.d.ts +70 -4
  74. package/dist/client.mjs +10 -7
  75. package/dist/config.d.mts +2 -1
  76. package/dist/config.d.ts +2 -1
  77. package/dist/{devtools-HE4FTUDN.mjs → devtools-LVC3VB5P.mjs} +4 -4
  78. package/dist/docs.cjs +11 -1
  79. package/dist/docs.cjs.map +1 -1
  80. package/dist/docs.mjs +4 -4
  81. package/dist/index.cjs +2112 -197
  82. package/dist/index.cjs.map +1 -1
  83. package/dist/index.d.mts +12 -11
  84. package/dist/index.d.ts +12 -11
  85. package/dist/index.mjs +49 -21
  86. package/dist/index.mjs.map +1 -1
  87. package/dist/integrations.d.mts +2 -1
  88. package/dist/integrations.d.ts +2 -1
  89. package/dist/internal/build-runtime.cjs +1455 -90
  90. package/dist/internal/build-runtime.cjs.map +1 -1
  91. package/dist/internal/build-runtime.d.mts +4 -3
  92. package/dist/internal/build-runtime.d.ts +4 -3
  93. package/dist/internal/build-runtime.mjs +15 -14
  94. package/dist/internal/config-runtime.cjs +12 -1
  95. package/dist/internal/config-runtime.cjs.map +1 -1
  96. package/dist/internal/config-runtime.d.mts +3 -2
  97. package/dist/internal/config-runtime.d.ts +3 -2
  98. package/dist/internal/config-runtime.mjs +3 -3
  99. package/dist/internal/production-runtime.cjs +282 -6
  100. package/dist/internal/production-runtime.cjs.map +1 -1
  101. package/dist/internal/production-runtime.d.mts +4 -4
  102. package/dist/internal/production-runtime.d.ts +4 -4
  103. package/dist/internal/production-runtime.mjs +4 -2
  104. package/dist/{metadata-eoVmHoyv.d.ts → metadata-BAPg_Nmo.d.ts} +1 -1
  105. package/dist/{metadata-Dp8AdvsB.d.mts → metadata-_6i9oFG3.d.mts} +1 -1
  106. package/dist/middleware.d.mts +4 -3
  107. package/dist/middleware.d.ts +4 -3
  108. package/dist/navigation.cjs +40 -15
  109. package/dist/navigation.cjs.map +1 -1
  110. package/dist/navigation.mjs +2 -2
  111. package/dist/plugin.cjs +913 -53
  112. package/dist/plugin.cjs.map +1 -1
  113. package/dist/plugin.d.mts +2 -1
  114. package/dist/plugin.d.ts +2 -1
  115. package/dist/plugin.mjs +11 -10
  116. package/dist/{production-runtime-BqTnUTai.d.ts → production-runtime-BoJDc5mc.d.ts} +1 -1
  117. package/dist/{production-runtime-DtDdG9fc.d.mts → production-runtime-DPfgMV9Y.d.mts} +1 -1
  118. package/dist/routes.cjs +276 -6
  119. package/dist/routes.cjs.map +1 -1
  120. package/dist/routes.d.mts +1 -1
  121. package/dist/routes.d.ts +1 -1
  122. package/dist/routes.mjs +3 -3
  123. package/dist/{runtime-C1B7pSGT.d.mts → runtime-9nQjVM7X.d.mts} +8 -9
  124. package/dist/{runtime-CdPHt0bv.d.ts → runtime-DgeS2skB.d.ts} +8 -9
  125. package/dist/server-action-security.cjs +28 -10
  126. package/dist/server-action-security.cjs.map +1 -1
  127. package/dist/server-action-security.d.mts +2 -1
  128. package/dist/server-action-security.d.ts +2 -1
  129. package/dist/server-action-security.mjs +2 -2
  130. package/dist/server-fn-client.d.mts +1 -0
  131. package/dist/server-fn-client.d.ts +1 -0
  132. package/dist/server-fn.cjs +785 -3
  133. package/dist/server-fn.cjs.map +1 -1
  134. package/dist/server-fn.d.mts +10 -1
  135. package/dist/server-fn.d.ts +10 -1
  136. package/dist/server-fn.mjs +6 -3
  137. package/dist/server-plugins.d.mts +3 -2
  138. package/dist/server-plugins.d.ts +3 -2
  139. package/dist/server-query-client.cjs +278 -7
  140. package/dist/server-query-client.cjs.map +1 -1
  141. package/dist/server-query-client.mjs +4 -4
  142. package/dist/server-query.cjs +381 -10
  143. package/dist/server-query.cjs.map +1 -1
  144. package/dist/server-query.mjs +5 -5
  145. package/dist/server.cjs +1086 -76
  146. package/dist/server.cjs.map +1 -1
  147. package/dist/server.d.mts +8 -7
  148. package/dist/server.d.ts +8 -7
  149. package/dist/server.mjs +31 -16
  150. package/dist/server.mjs.map +1 -1
  151. package/dist/testing.cjs +341 -20
  152. package/dist/testing.cjs.map +1 -1
  153. package/dist/testing.d.mts +3 -2
  154. package/dist/testing.d.ts +3 -2
  155. package/dist/testing.mjs +7 -6
  156. package/dist/testing.mjs.map +1 -1
  157. package/dist/transport-BmbGTXA5.d.mts +49 -0
  158. package/dist/transport-BmbGTXA5.d.ts +49 -0
  159. package/dist/{utils-8USa5BiY.d.mts → utils-CHXlMDkg.d.mts} +1 -1
  160. package/dist/{utils-DKJb6K6G.d.ts → utils-Drsyz1Vj.d.ts} +1 -1
  161. package/dist/version.cjs +1 -1
  162. package/dist/version.cjs.map +1 -1
  163. package/dist/version.mjs +1 -1
  164. package/dist/vite.cjs +914 -54
  165. package/dist/vite.cjs.map +1 -1
  166. package/dist/vite.d.mts +2 -1
  167. package/dist/vite.d.ts +2 -1
  168. package/dist/vite.mjs +11 -10
  169. package/package.json +1 -1
  170. package/types/api.d.ts +44 -0
  171. package/types/client.d.ts +85 -4
  172. package/dist/chunk-45LKHSHJ.mjs.map +0 -1
  173. package/dist/chunk-5FW6PQ3J.mjs.map +0 -1
  174. package/dist/chunk-6VS6CKAV.mjs.map +0 -1
  175. package/dist/chunk-C33RALN7.mjs.map +0 -1
  176. package/dist/chunk-GZWT6VI5.mjs +0 -382
  177. package/dist/chunk-GZWT6VI5.mjs.map +0 -1
  178. package/dist/chunk-HZYXGV4K.mjs.map +0 -1
  179. package/dist/chunk-LWMGIEJA.mjs.map +0 -1
  180. package/dist/chunk-OHC6VCDI.mjs.map +0 -1
  181. package/dist/chunk-SHRJG6OG.mjs.map +0 -1
  182. package/dist/chunk-T543TMFY.mjs.map +0 -1
  183. package/dist/chunk-XJSHJN4M.mjs.map +0 -1
  184. package/dist/chunk-XUBZ7JI4.mjs.map +0 -1
  185. /package/dist/{chunk-5QH4IKY3.mjs.map → chunk-3U3ZUQAQ.mjs.map} +0 -0
  186. /package/dist/{chunk-CSU4KJJF.mjs.map → chunk-C2ROET2V.mjs.map} +0 -0
  187. /package/dist/{chunk-BIOIOWXZ.mjs.map → chunk-HNIQFZKB.mjs.map} +0 -0
  188. /package/dist/{chunk-G5I34UA6.mjs.map → chunk-JDEOUK5V.mjs.map} +0 -0
  189. /package/dist/{chunk-MH6FKW2I.mjs.map → chunk-SADGIRS2.mjs.map} +0 -0
  190. /package/dist/{chunk-NRRFGX45.mjs.map → chunk-TQAEEJB4.mjs.map} +0 -0
  191. /package/dist/{chunk-LG3YINQN.mjs.map → chunk-Z5CQMP54.mjs.map} +0 -0
  192. /package/dist/{devtools-HE4FTUDN.mjs.map → devtools-LVC3VB5P.mjs.map} +0 -0
@@ -1,5 +1,5 @@
1
1
  import { ChildProcess } from 'node:child_process';
2
- import { U as BundleResultPayload, V as FarmPlugin, W as FarmIntegration } from './client-plugins-Cnr0D3kk.mjs';
2
+ import { U as BundleResultPayload, V as FarmPlugin, W as FarmIntegration } from './client-plugins-DQQ1adXM.mjs';
3
3
  import './plugin-BJDf43dc.mjs';
4
4
  import 'react';
5
5
  import 'http';
@@ -19,6 +19,7 @@ import './env.mjs';
19
19
  import './server-action-security.mjs';
20
20
  import './image-config-Duob7wER.mjs';
21
21
  import './types-BH1lhg5G.mjs';
22
+ import './cache.mjs';
22
23
  import './route-runtime-DoOHzCAD.mjs';
23
24
 
24
25
  interface FarmAgentRuntimeInstance {
@@ -1,5 +1,5 @@
1
1
  import { ChildProcess } from 'node:child_process';
2
- import { U as BundleResultPayload, V as FarmPlugin, W as FarmIntegration } from './client-plugins-CTnsZz_A.js';
2
+ import { U as BundleResultPayload, V as FarmPlugin, W as FarmIntegration } from './client-plugins-Cw4qUGsw.js';
3
3
  import './plugin-BJDf43dc.js';
4
4
  import 'react';
5
5
  import 'http';
@@ -19,6 +19,7 @@ import './env.js';
19
19
  import './server-action-security.js';
20
20
  import './image-config-Duob7wER.js';
21
21
  import './types-BH1lhg5G.js';
22
+ import './cache.js';
22
23
  import './route-runtime-DoOHzCAD.js';
23
24
 
24
25
  interface FarmAgentRuntimeInstance {
@@ -202,11 +202,51 @@ __name(_setFarmI18nSnapshotResolver, "_setFarmI18nSnapshotResolver");
202
202
 
203
203
  // src/cache.ts
204
204
  var _FarmDataCache = class _FarmDataCache {
205
- constructor() {
205
+ constructor(config = {}) {
206
206
  this.entries = /* @__PURE__ */ new Map();
207
207
  this.inflight = /* @__PURE__ */ new Map();
208
208
  this.invalidatedTagVersions = /* @__PURE__ */ new Map();
209
209
  this.version = 0;
210
+ this.namespace = "farm";
211
+ this.local = true;
212
+ this.lease = {
213
+ enabled: true,
214
+ ttlMs: 1e4,
215
+ waitTimeoutMs: 1e4,
216
+ pollIntervalMs: 25
217
+ };
218
+ this.configure(config);
219
+ }
220
+ configure(config = {}) {
221
+ this.adapter = config.adapter;
222
+ this.namespace = normalizeCacheNamespace(config.namespace || "farm");
223
+ this.local = !config.adapter;
224
+ this.lease = config.lease === false ? { ...this.lease, enabled: false } : {
225
+ enabled: true,
226
+ ttlMs: normalizePositiveDuration(config.lease?.ttlMs, 1e4, "cache.lease.ttlMs"),
227
+ waitTimeoutMs: normalizePositiveDuration(
228
+ config.lease?.waitTimeoutMs,
229
+ 1e4,
230
+ "cache.lease.waitTimeoutMs"
231
+ ),
232
+ pollIntervalMs: normalizePositiveDuration(
233
+ config.lease?.pollIntervalMs,
234
+ 25,
235
+ "cache.lease.pollIntervalMs"
236
+ )
237
+ };
238
+ if (!this.local) {
239
+ this.entries.clear();
240
+ this.inflight.clear();
241
+ this.invalidatedTagVersions.clear();
242
+ this.version = 0;
243
+ }
244
+ }
245
+ get adapterName() {
246
+ return this.adapter?.name || (this.adapter ? "custom" : "memory");
247
+ }
248
+ get hasAdapter() {
249
+ return this.adapter !== void 0;
210
250
  }
211
251
  get size() {
212
252
  return this.entries.size;
@@ -242,6 +282,45 @@ var _FarmDataCache = class _FarmDataCache {
242
282
  });
243
283
  return this.toPublicEntry(entry);
244
284
  }
285
+ async getEntryAsync(key, options = {}) {
286
+ if (this.local) {
287
+ const localEntry = this.getEntry(key, options);
288
+ if (localEntry) return localEntry;
289
+ }
290
+ if (!this.adapter) {
291
+ return this.local ? void 0 : this.getEntry(key, options);
292
+ }
293
+ const entry = await this.adapter.get(this.createAdapterKey(key));
294
+ if (!entry) {
295
+ emitFarmEvent({ type: "cache.miss", key });
296
+ return void 0;
297
+ }
298
+ assertFarmCacheEntry(entry, key);
299
+ const stale = await this.isAdapterEntryStale(entry, options.now);
300
+ if (stale) {
301
+ emitFarmEvent({
302
+ type: "cache.stale",
303
+ key,
304
+ tags: [...entry.tags],
305
+ revalidate: entry.revalidate
306
+ });
307
+ if (!options.allowStale) {
308
+ emitFarmEvent({ type: "cache.miss", key, reason: "stale" });
309
+ return void 0;
310
+ }
311
+ }
312
+ emitFarmEvent({
313
+ type: "cache.hit",
314
+ key,
315
+ tags: [...entry.tags],
316
+ revalidate: entry.revalidate,
317
+ stale
318
+ });
319
+ if (this.local && !stale) {
320
+ this.hydrateLocalEntry(entry);
321
+ }
322
+ return { ...entry, key };
323
+ }
245
324
  set(key, value, options = {}) {
246
325
  const tags = /* @__PURE__ */ new Set();
247
326
  for (const tag of options.tags ?? []) {
@@ -254,6 +333,7 @@ var _FarmDataCache = class _FarmDataCache {
254
333
  key,
255
334
  value,
256
335
  tags,
336
+ tagVersions: void 0,
257
337
  createdAt: options.createdAt ?? Date.now(),
258
338
  createdVersion: ++this.version,
259
339
  revalidate: normalizeRevalidate(options.revalidate)
@@ -267,11 +347,45 @@ var _FarmDataCache = class _FarmDataCache {
267
347
  });
268
348
  return this.toPublicEntry(entry);
269
349
  }
350
+ async setAsync(key, value, options = {}, tagVersions) {
351
+ const tags = normalizeCacheOptionsTags(options);
352
+ const capturedVersions = tagVersions ?? await this.getAdapterTagVersions(Array.from(tags.values()));
353
+ const entry = {
354
+ key,
355
+ value,
356
+ tags: Array.from(tags),
357
+ tagVersions: capturedVersions,
358
+ createdAt: options.createdAt ?? Date.now(),
359
+ createdVersion: ++this.version,
360
+ revalidate: normalizeRevalidate(options.revalidate)
361
+ };
362
+ if (this.local) {
363
+ this.hydrateLocalEntry(entry);
364
+ }
365
+ if (this.adapter) {
366
+ await this.adapter.set(this.createAdapterKey(key), entry);
367
+ }
368
+ emitFarmEvent({
369
+ type: "cache.set",
370
+ key,
371
+ tags: [...entry.tags],
372
+ revalidate: entry.revalidate
373
+ });
374
+ return entry;
375
+ }
270
376
  delete(key) {
271
377
  const deleted = this.entries.delete(key);
272
378
  emitFarmEvent({ type: "cache.delete", key, deleted });
273
379
  return deleted;
274
380
  }
381
+ async deleteAsync(key) {
382
+ const deleted = this.entries.delete(key);
383
+ if (this.adapter) {
384
+ await this.adapter.delete(this.createAdapterKey(key));
385
+ }
386
+ emitFarmEvent({ type: "cache.delete", key, deleted: this.adapter ? true : deleted });
387
+ return this.adapter ? true : deleted;
388
+ }
275
389
  clear() {
276
390
  const count = this.entries.size;
277
391
  this.entries.clear();
@@ -280,6 +394,10 @@ var _FarmDataCache = class _FarmDataCache {
280
394
  this.version = 0;
281
395
  emitFarmEvent({ type: "cache.clear", count });
282
396
  }
397
+ async clearAsync() {
398
+ this.clear();
399
+ await this.adapter?.clear?.();
400
+ }
283
401
  isStale(entry, now = Date.now()) {
284
402
  if (typeof entry.revalidate === "number" && entry.revalidate > 0 && now - entry.createdAt >= entry.revalidate * 1e3) {
285
403
  return true;
@@ -292,6 +410,12 @@ var _FarmDataCache = class _FarmDataCache {
292
410
  }
293
411
  return false;
294
412
  }
413
+ async isStaleAsync(entry, now = Date.now()) {
414
+ if (this.adapter) {
415
+ return this.isAdapterEntryStale(entry, now);
416
+ }
417
+ return this.isStale(entry, now);
418
+ }
295
419
  revalidateTag(tag, options = {}) {
296
420
  const normalized = normalizeCacheTag(tag);
297
421
  const count = this.invalidateTag(normalized);
@@ -300,6 +424,15 @@ var _FarmDataCache = class _FarmDataCache {
300
424
  );
301
425
  return count;
302
426
  }
427
+ async revalidateTagAsync(tag, options = {}) {
428
+ const normalized = normalizeCacheTag(tag);
429
+ const count = this.invalidateTag(normalized);
430
+ await this.adapter?.invalidateTags?.([this.createAdapterTag(normalized)]);
431
+ emitFarmEvent(
432
+ options.source === "updateTag" ? { type: "cache.updateTag", tag: normalized, count } : { type: "cache.revalidateTag", tag: normalized, profile: options.profile, count }
433
+ );
434
+ return count;
435
+ }
303
436
  revalidatePath(routePath) {
304
437
  const normalizedPath = normalizeRevalidatePath(routePath);
305
438
  const pathTag = createPathCacheTag(normalizedPath);
@@ -316,8 +449,25 @@ var _FarmDataCache = class _FarmDataCache {
316
449
  }
317
450
  return count;
318
451
  }
452
+ async revalidatePathAsync(routePath) {
453
+ const normalizedPath = normalizeRevalidatePath(routePath);
454
+ const pathTag = createPathCacheTag(normalizedPath);
455
+ const pprCount = this.countEntriesForTags([pathTag, "ppr"]);
456
+ const count = this.invalidateTag(pathTag);
457
+ await this.adapter?.invalidateTags?.([this.createAdapterTag(pathTag)]);
458
+ emitFarmEvent({ type: "cache.revalidatePath", path: normalizedPath, count });
459
+ if (pprCount > 0) {
460
+ emitFarmEvent({
461
+ type: "ppr.shell.invalidated",
462
+ route: normalizedPath,
463
+ reason: "revalidatePath",
464
+ count: pprCount
465
+ });
466
+ }
467
+ return count;
468
+ }
319
469
  async getOrSet(key, producer, options = {}) {
320
- const cached = this.getEntry(key);
470
+ const cached = await this.getEntryAsync(key);
321
471
  if (cached) {
322
472
  return cached.value;
323
473
  }
@@ -326,10 +476,8 @@ var _FarmDataCache = class _FarmDataCache {
326
476
  emitFarmEvent({ type: "cache.dedupe", key });
327
477
  return inflight;
328
478
  }
329
- const promise = Promise.resolve().then(producer).then((value) => {
330
- this.set(key, value, options);
331
- return value;
332
- }).catch((error) => {
479
+ const tags = Array.from(normalizeCacheOptionsTags(options));
480
+ const promise = this.fillCacheEntry(key, producer, options, tags).catch((error) => {
333
481
  emitFarmEvent({ type: "cache.error", key, operation: "set", error });
334
482
  throw error;
335
483
  }).finally(() => {
@@ -338,6 +486,40 @@ var _FarmDataCache = class _FarmDataCache {
338
486
  this.inflight.set(key, promise);
339
487
  return promise;
340
488
  }
489
+ async fillCacheEntry(key, producer, options, tags) {
490
+ const leaseKey = `${this.namespace}:lease:${key}`;
491
+ let leaseToken;
492
+ if (this.adapter?.acquireLease && this.adapter.releaseLease && this.lease.enabled) {
493
+ leaseToken = await this.adapter.acquireLease(leaseKey, this.lease.ttlMs);
494
+ if (!leaseToken) {
495
+ const shared = await this.waitForAdapterEntry(key);
496
+ if (shared) {
497
+ emitFarmEvent({ type: "cache.dedupe", key });
498
+ return shared.value;
499
+ }
500
+ leaseToken = await this.adapter.acquireLease(leaseKey, this.lease.ttlMs);
501
+ }
502
+ }
503
+ try {
504
+ const initialTagVersions = await this.getAdapterTagVersions(tags);
505
+ const value = await producer();
506
+ await this.setAsync(key, value, options, initialTagVersions);
507
+ return value;
508
+ } finally {
509
+ if (leaseToken && this.adapter?.releaseLease) {
510
+ await this.adapter.releaseLease(leaseKey, leaseToken);
511
+ }
512
+ }
513
+ }
514
+ async waitForAdapterEntry(key) {
515
+ const deadline = Date.now() + this.lease.waitTimeoutMs;
516
+ while (Date.now() < deadline) {
517
+ await delay(this.lease.pollIntervalMs);
518
+ const entry = await this.getEntryAsync(key);
519
+ if (entry) return entry;
520
+ }
521
+ return void 0;
522
+ }
341
523
  countEntriesForTag(tag) {
342
524
  let count = 0;
343
525
  for (const entry of this.entries.values()) {
@@ -365,11 +547,53 @@ var _FarmDataCache = class _FarmDataCache {
365
547
  key: entry.key,
366
548
  value: entry.value,
367
549
  tags: Array.from(entry.tags),
550
+ tagVersions: entry.tagVersions,
368
551
  createdAt: entry.createdAt,
369
552
  createdVersion: entry.createdVersion,
370
553
  revalidate: entry.revalidate
371
554
  };
372
555
  }
556
+ hydrateLocalEntry(entry) {
557
+ this.entries.set(entry.key, {
558
+ key: entry.key,
559
+ value: entry.value,
560
+ tags: new Set(entry.tags.map(normalizeCacheTag)),
561
+ tagVersions: entry.tagVersions,
562
+ createdAt: entry.createdAt,
563
+ createdVersion: entry.createdVersion ?? ++this.version,
564
+ revalidate: normalizeRevalidate(entry.revalidate)
565
+ });
566
+ }
567
+ createAdapterKey(key) {
568
+ return `${this.namespace}:entry:${key}`;
569
+ }
570
+ createAdapterTag(tag) {
571
+ return `${this.namespace}:tag:${tag}`;
572
+ }
573
+ async getAdapterTagVersions(tags) {
574
+ if (!this.adapter?.getTagVersions || tags.length === 0) return {};
575
+ const normalized = tags.map(normalizeCacheTag);
576
+ const physicalTags = normalized.map((tag) => this.createAdapterTag(tag));
577
+ const versions = await this.adapter.getTagVersions(physicalTags);
578
+ return Object.fromEntries(
579
+ normalized.map((tag, index) => [
580
+ tag,
581
+ normalizeAdapterVersion(versions[physicalTags[index]])
582
+ ])
583
+ );
584
+ }
585
+ async isAdapterEntryStale(entry, now = Date.now()) {
586
+ if (typeof entry.revalidate === "number" && entry.revalidate > 0 && now - entry.createdAt >= entry.revalidate * 1e3) {
587
+ return true;
588
+ }
589
+ const currentVersions = await this.getAdapterTagVersions(entry.tags);
590
+ for (const tag of entry.tags) {
591
+ if (normalizeAdapterVersion(currentVersions[tag]) > normalizeAdapterVersion(entry.tagVersions?.[tag])) {
592
+ return true;
593
+ }
594
+ }
595
+ return false;
596
+ }
373
597
  };
374
598
  __name(_FarmDataCache, "FarmDataCache");
375
599
  var FarmDataCache = _FarmDataCache;
@@ -424,6 +648,52 @@ function normalizeCacheTag(tag) {
424
648
  return normalized;
425
649
  }
426
650
  __name(normalizeCacheTag, "normalizeCacheTag");
651
+ function normalizeCacheNamespace(namespace) {
652
+ if (typeof namespace !== "string") {
653
+ throw new TypeError("Cache namespace must be a string.");
654
+ }
655
+ const normalized = namespace.trim().replace(/:+$/g, "");
656
+ if (!normalized) {
657
+ throw new Error("Cache namespace cannot be empty.");
658
+ }
659
+ return normalized;
660
+ }
661
+ __name(normalizeCacheNamespace, "normalizeCacheNamespace");
662
+ function normalizeAdapterVersion(value) {
663
+ return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : 0;
664
+ }
665
+ __name(normalizeAdapterVersion, "normalizeAdapterVersion");
666
+ function normalizePositiveDuration(value, fallback, name) {
667
+ if (value === void 0) return fallback;
668
+ if (!Number.isFinite(value) || value <= 0) {
669
+ throw new TypeError(`${name} must be a positive number of milliseconds.`);
670
+ }
671
+ return Math.floor(value);
672
+ }
673
+ __name(normalizePositiveDuration, "normalizePositiveDuration");
674
+ function delay(ms) {
675
+ return new Promise((resolve) => setTimeout(resolve, ms));
676
+ }
677
+ __name(delay, "delay");
678
+ function normalizeCacheOptionsTags(options) {
679
+ const tags = /* @__PURE__ */ new Set();
680
+ for (const tag of options.tags ?? []) {
681
+ tags.add(normalizeCacheTag(tag));
682
+ }
683
+ for (const routePath of options.paths ?? []) {
684
+ tags.add(createPathCacheTag(routePath));
685
+ }
686
+ return tags;
687
+ }
688
+ __name(normalizeCacheOptionsTags, "normalizeCacheOptionsTags");
689
+ function assertFarmCacheEntry(entry, expectedKey) {
690
+ if (!entry || typeof entry !== "object" || entry.key !== expectedKey || !Array.isArray(entry.tags) || typeof entry.createdAt !== "number") {
691
+ throw new TypeError(
692
+ `Cache adapter returned an invalid entry for ${JSON.stringify(expectedKey)}.`
693
+ );
694
+ }
695
+ }
696
+ __name(assertFarmCacheEntry, "assertFarmCacheEntry");
427
697
 
428
698
  // src/route-runtime.ts
429
699
  function normalizeFarmRouteRuntimeConfig(value, source = "Route configuration") {
@@ -812,7 +1082,7 @@ async function invokeAPIRouteEndpointInContext(endpoint, request, params) {
812
1082
  });
813
1083
  let body = void 0;
814
1084
  if (request.method.toUpperCase() !== "GET" && request.method.toUpperCase() !== "HEAD") {
815
- body = await readJSONBody(request);
1085
+ body = await readRequestBody(request);
816
1086
  }
817
1087
  const headers = Object.fromEntries(request.headers.entries());
818
1088
  const types = endpoint.__types || {};
@@ -916,17 +1186,50 @@ function isFarmContextHandler(endpoint) {
916
1186
  return firstParameter === "ctx" || firstParameter === "context" || firstParameter.startsWith("{");
917
1187
  }
918
1188
  __name(isFarmContextHandler, "isFarmContextHandler");
919
- async function readJSONBody(request) {
1189
+ async function readRequestBody(request) {
1190
+ const contentType = request.headers.get("content-type")?.split(";", 1)[0]?.trim().toLowerCase();
920
1191
  try {
1192
+ if (contentType === "multipart/form-data") {
1193
+ return formDataToObject(await request.clone().formData());
1194
+ }
921
1195
  const text = await request.clone().text();
922
- if (text) {
1196
+ if (!text) return void 0;
1197
+ if (contentType === "application/x-www-form-urlencoded") {
1198
+ return searchParamsToObject(new URLSearchParams(text));
1199
+ }
1200
+ if (contentType === "application/json" || contentType?.endsWith("+json")) {
923
1201
  return JSON.parse(text);
924
1202
  }
1203
+ return JSON.parse(text);
925
1204
  } catch {
926
1205
  }
927
1206
  return void 0;
928
1207
  }
929
- __name(readJSONBody, "readJSONBody");
1208
+ __name(readRequestBody, "readRequestBody");
1209
+ function formDataToObject(formData) {
1210
+ return entriesToObject(formData.entries());
1211
+ }
1212
+ __name(formDataToObject, "formDataToObject");
1213
+ function searchParamsToObject(searchParams) {
1214
+ return entriesToObject(searchParams.entries());
1215
+ }
1216
+ __name(searchParamsToObject, "searchParamsToObject");
1217
+ function entriesToObject(entries) {
1218
+ const output = /* @__PURE__ */ Object.create(null);
1219
+ for (const [key, value] of entries) {
1220
+ if (key === "__proto__" || key === "constructor" || key === "prototype") continue;
1221
+ const current = output[key];
1222
+ if (current === void 0) {
1223
+ output[key] = value;
1224
+ } else if (Array.isArray(current)) {
1225
+ current.push(value);
1226
+ } else {
1227
+ output[key] = [current, value];
1228
+ }
1229
+ }
1230
+ return output;
1231
+ }
1232
+ __name(entriesToObject, "entriesToObject");
930
1233
  function validateInput(schema, value, error) {
931
1234
  if (!schema || typeof schema.parse !== "function") {
932
1235
  return value;